use ratatui::{buffer::Buffer, layout::Rect, style::Style, widgets::{List, ListItem, Widget}};

use crate::{config::THEME, core::{self, files::File}, misc::readable_path, ui::Ctx};

pub struct Folder<'a> {
    cx:           &'a Ctx,  // 应用上下文 包含MIME主题 主题配置全局信息
    folder:       &'a core::manager::Folder,  // 当前文件夹的状态
    is_preview:   bool,  // 是否处于预览模式
    is_selection: bool, // 是否处于选择模式
}

impl<'a> Folder<'a> {
    pub fn new(cx: &'a Ctx, folder: &'a core::manager::Folder) -> Self {
        Self { cx, folder, is_preview: false, is_selection: true }
    }

    #[inline]
    // 用于链式调用  链式设置预览模式
    pub fn with_preview(mut self, state: bool) -> Self {
        self.is_preview = state;
        self
    }

    #[inline]
    // 链式设置选择模式
    pub fn with_selection(mut self, state: bool) -> Self {
        self.is_selection = state;
        self
    }

    #[inline]
    fn file_style(&self, file: &File) -> Style {
        let mimetype = &self.cx.manager.mimetype;
        THEME
            .filetypes
            .iter()
            .find(|x| x.matches(&file.path, mimetype.get(&file.path).cloned(), file.meta.is_dir()))
            .map(|x| x.style.get())
            .unwrap_or_else(|| Style::new())
    }
}

impl<'a> Widget for Folder<'a> {
    fn render(self, area: Rect, buf: &mut Buffer) {
        let window = self.folder.window();   // 获取当前可见窗口的文件列表

        let items = window
            .iter()
            .enumerate()
            .map(|(i, (k, v))| {
                // 获取文件图标
                let icon = THEME
                    .icons
                    .iter()
                    .find(|x| x.name.match_path(k, Some(v.meta.is_dir())))
                    .map(|x| x.display.as_ref())
                    .unwrap_or("");
                // 处理选中标记
                if v.is_selected {
                    buf.set_style(
                        Rect { x: area.x.saturating_sub(1), y: i as u16 + 1, width: 1, height: 1 },
                        if self.is_selection {
                            THEME.marker.selecting.get()
                        } else {
                            THEME.marker.selected.get()
                        },
                    );
                }

                // 处理悬停样式
                let hovered = matches!(self.folder.hovered, Some(ref h) if h.path == *k);
                let style = if self.is_preview && hovered {
                    THEME.preview.hovered.get()
                } else if hovered {
                    THEME.selection.hovered.get()
                } else {
                    self.file_style(v)
                };
                // 创建列表项
                ListItem::new(format!(" {} {}", icon, readable_path(k, &self.folder.cwd))).style(style)
            })
            .collect::<Vec<_>>();
        // 渲染列表
        List::new(items).render(area, buf);
    }
}
